package cc.rengu.igas.mcps.core.service.trans.common;

import cc.rengu.igas.mcps.common.constant.McpsTxnNumConstant;
import cc.rengu.igas.mcps.common.dao.TxnMapper;
import cc.rengu.igas.mcps.common.dao.impl.TxnMapperImpl;
import cc.rengu.igas.mcps.common.entity.TransAmtInfo;
import cc.rengu.igas.mcps.common.enums.RespCodeEnum;
import cc.rengu.igas.mcps.core.service.base.ManageService;
import cc.rengu.igas.mcps.facade.bean.CollectData;
import cc.rengu.igas.mcps.facade.request.PosBatchSettleRequest;
import cc.rengu.igas.mcps.facade.response.PosBatchSettleResponse;
import cc.rengu.igas.share.core.model.MchntTermInfo;
import cc.rengu.igas.share.core.realize.MchntService;
import cc.rengu.igas.share.core.realize.impl.MchntServiceImpl;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.model.BizResponse;
import cc.rengu.oltp.utility.util.AmountUtil;
import cc.rengu.oltp.utility.util.ConvertUtil;
import cc.rengu.oltp.utility.util.StringUtil;

import java.util.ArrayList;
import java.util.List;

/**
 * 批结算	M00MC003
 */
public class TermBatchSettleService extends ManageService {
    @Override
    protected Object bizBeforeCust() throws Exception {
        PosBatchSettleRequest posBatchSettleRequest = new PosBatchSettleRequest();
        ConvertUtil.convertOutput(posBatchSettleRequest);
        return posBatchSettleRequest;
    }

    @Override
    protected BizResponse bizProcessCust(Object request) throws Exception {
        PosBatchSettleRequest posBatchSettleReq = (PosBatchSettleRequest) request;
        String mchntNo = posBatchSettleReq.getMchntNo();
        String termNo = posBatchSettleReq.getTermNo();
        String batchNo = posBatchSettleReq.getBatchNo();

        List<CollectData> termCollectDataList = posBatchSettleReq.getTermCollectDataList();

        TxnMapper txnMapper = new TxnMapperImpl();
        List<CollectData> resultCollectDataList = new ArrayList<>(termCollectDataList.size());
        //查询结果，通过商户号，终端号，批次号，币种，交易类型等信息，查询借贷金额，借贷笔数
        for (CollectData termCollectData : termCollectDataList) {
            //初始化为：1-对账平
            termCollectData.setResult("1");

            String debitTotalAmt = "0";
            int debitTotalNum = 0;
            String creditTotalAmt = "0";
            int creditTotalNum = 0;

            //1.计算交易流水表 借记金额，借记笔数 （消费-P01MC001，预授权完成-P06MC502
            // 条码扫码支付（被扫）-P01MC006），条码主扫P01MC003，分期消费P01MC011
            List<String> debitTxnNumList = new ArrayList<>(5);
            debitTxnNumList.add(McpsTxnNumConstant.NPOS_CONSUME_TXN_NUM); //消费-P01MC001
            debitTxnNumList.add(McpsTxnNumConstant.AUTH_COMP_TXN_NUM); //预授权完成-P06MC502
            debitTxnNumList.add(McpsTxnNumConstant.NPOS_QR_CONSUME_TXN_NUM); //条码扫码支付（被扫）-P01MC006
            debitTxnNumList.add(McpsTxnNumConstant.NPOS_QR_SCAN_CONSUME_TXN_NUM); //条码扫码支付（主扫）-P01MC003
            debitTxnNumList.add(McpsTxnNumConstant.NPOS_INSTALL_TXN_NUM); //分期-P01MC011
            for (String debitTxnNum : debitTxnNumList) {
                TransAmtInfo transAmtInfo = txnMapper.selectTransAmtAndTransNumByCondition(mchntNo, termNo,
                        debitTxnNum, batchNo, termCollectData.getTransCcy());
                if (null != transAmtInfo) {
                    debitTotalAmt = AmountUtil.addition(debitTotalAmt, transAmtInfo.getTransAmt());
                    debitTotalNum += transAmtInfo.getTransNum();
                }
            }

            //2.计算交易流水表 贷记金额，贷记笔数 （消费撤销-P03MC001，消费退货-P04MC001，预授权完成撤销-P06MC702，
            // 条码消费撤销-P03MC006，条码消费退货-P04MC004,分期消费撤销-P03MC011 ,分期消费退货-P04MC011）
            List<String> creditTxnNumList = new ArrayList<>(7);
            creditTxnNumList.add(McpsTxnNumConstant.NPOS_CANCEL_TXN_NUM); //消费撤销-P03MC001
            creditTxnNumList.add(McpsTxnNumConstant.NPOS_REFUND_TXN_NUM); //消费退货-P04MC001
            creditTxnNumList.add(McpsTxnNumConstant.AUTH_COMP_CANCEL_TXN_NUM); //预授权完成撤销-P06MC702
            creditTxnNumList.add(McpsTxnNumConstant.NPOS_QR_CONSUME_CANCEL_TXN_NUM); //条码消费撤销-P03MC006
            creditTxnNumList.add(McpsTxnNumConstant.NPOS_QR_CONSUME_REFUND_TXN_NUM); //条码消费退货-P04MC004
            creditTxnNumList.add(McpsTxnNumConstant.NPOS_INSTALL_CANCEL_TXN_NUM); //分期消费撤销-P03MC011
            creditTxnNumList.add(McpsTxnNumConstant.NPOS_INSTALL_REFUND_TXN_NUM); //分期消费退货-P04MC011
            for (String creditTxn : creditTxnNumList) {
                TransAmtInfo transAmtInfo = txnMapper.selectTransAmtAndTransNumByCondition(mchntNo, termNo,
                        creditTxn, batchNo, termCollectData.getTransCcy());
                if (null != transAmtInfo) {
                    creditTotalNum += transAmtInfo.getTransNum();
                    creditTotalAmt = AmountUtil.addition(creditTotalAmt, transAmtInfo.getTransAmt());
                }
            }

            //3.进行金额与笔数校验
            setReconciliationResult(termCollectData, debitTotalAmt, debitTotalNum, creditTotalAmt, creditTotalNum);

            resultCollectDataList.add(termCollectData);
        }

        //更新批次号
        /* 获取终端信息 */
        MchntService mchntService = new MchntServiceImpl();
        MchntTermInfo mchntTermInfo = mchntService.getMchntTermInfo(posBatchSettleReq.getHeader().getInstId(), posBatchSettleReq.getMchntNo(), posBatchSettleReq.getTermNo());
        if (!StringUtil.isEmptyOrNull(mchntTermInfo.getBatchNo())) {
            /*更新批次号*/
            if ("999999".equals(mchntTermInfo.getBatchNo())) {
                batchNo = String.format("%06d", 1);
            } else {
                batchNo = String.format("%06d", Integer.parseInt(mchntTermInfo.getBatchNo()) + 1);
            }
        }
        mchntTermInfo.setBatchNo(batchNo);
        boolean updateFlag = mchntService.updateMchntTermInfo("00", mchntTermInfo);
        if (!updateFlag) {
            rglog.error("更新终端状态失败");
            throw new BizException(RespCodeEnum.UPDATE_TERM_INFO_ERROR.getRespCode(), RespCodeEnum.UPDATE_TERM_INFO_ERROR.getRespDesc());
        }

        /* 重组响应结果 */
        PosBatchSettleResponse posBatchSettleRsp = new PosBatchSettleResponse();
        ConvertUtil.convertOutput(posBatchSettleRsp);
        posBatchSettleRsp.setTermCollectDataList(resultCollectDataList);
        posBatchSettleRsp.setBatchNo(batchNo);
        BizResponse bizResponse = new BizResponse();
        bizResponse.setRspSysId(AppParamConstant.SYS_ID);
        bizResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
        bizResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
        bizResponse.setResult(posBatchSettleRsp);
        return bizResponse;
    }


    @Override
    protected void bizAfterCust(Object response) throws Exception {
        BizResponse bizResponse = (BizResponse) response;
        PosBatchSettleResponse posBatchSettleResponse = (PosBatchSettleResponse) bizResponse.getResult();
        ConvertUtil.convertInput(posBatchSettleResponse);
    }

    private void setReconciliationResult(CollectData termCollectData, String debitTotalAmt, int debitTotalNum, String creditTotalAmt, int creditTotalNum) {
        //借记金额校验
        String orderDebitAmt = AmountUtil.division(debitTotalAmt, "100");
        if (AmountUtil.compare(orderDebitAmt, termCollectData.getDebitTotalAmt()) != 0) {
            rglog.error("对账金额不一致,数据库总金额orderDebitAmt:<{}>,通知金额txnAmt=<{}>", orderDebitAmt, termCollectData.getDebitTotalAmt());
            termCollectData.setResult("2"); //对账不平
        }

        //借记笔数校验
        String orderDebitNum = String.valueOf(debitTotalNum);
        if (AmountUtil.compare(orderDebitNum, termCollectData.getDebitTotalNum()) != 0) {
            rglog.error("对账笔数不一致,数据库总笔数orderDebitNum:<{}>,通知笔数txnNum=<{}>", orderDebitNum, termCollectData.getDebitTotalNum());
            termCollectData.setResult("2"); //对账不平
        }

        //贷记金额校验
        String orderCreditAmt = AmountUtil.division(creditTotalAmt, "100");
        if (AmountUtil.compare(orderCreditAmt, termCollectData.getCreditTotalAmt()) != 0) {
            rglog.error("对账金额不一致,数据库总金额orderCreditAmt:<{}>,通知金额txnAmt=<{}>", orderCreditAmt, termCollectData.getCreditTotalAmt());
            termCollectData.setResult("2"); //对账不平
        }

        //贷记笔数校验
        String orderCreditNum = String.valueOf(creditTotalNum);
        if (AmountUtil.compare(orderCreditNum, termCollectData.getCreditTotalNum()) != 0) {
            rglog.error("对账笔数不一致,数据库总笔数orderCreditNum:<{}>,通知笔数txnNum=<{}>", orderCreditNum, termCollectData.getCreditTotalNum());
            termCollectData.setResult("2"); //对账不平
        }
    }

}
